Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intel 8080 Emulator for the Atari 130XE and the BBC Master #134

Open
wants to merge 28 commits into
base: master
Choose a base branch
from

Conversation

ivop
Copy link
Contributor

@ivop ivop commented Apr 4, 2024

Hi,

This is the Atari 130XE 8080 emulator overlay loader. I did not include the whole source tree of https://github.com/ivop/atari8080 but just the assembled overlay and a few 8080 sample files. If you want Zork dropped because of licensing issues, I can create a new pull request. Do you know any other 8080 only software that could be included? Most interesting stuff I found is Z80 only.

Here's a small video demonstrating how it works:

https://youtu.be/oHrtUj0fEk0

I briefly looked into porting it to the BBC. I think it could be fairly straight forward with the 16kB banking window at $8000-$bfff. Incrementing the 8080 program counter will be slightly slower though, because the bpl trick cannot be used. The Atari's window is at $4000-$7fff, so then the high byte overflows, the N flag is set. On the BBC you'll need to load it into A, compare with $c0 and use bcc instead of bpl. That'll especially affect short instructions, like MOV, but ALU stuff not so much. Also, the banking register and its values have to be changed and setting/resetting the background color. The rest is platform agnostic. Oh, and the handling of overflowing the bank during a sector read and write needs to be handled differently, as there is no RAM after the bank like on the Atari. And the overlay loader needs to be changed slightly, e.g. check for BBC extended memory instead of the 130XE scheme.

I'm not sure I know enough about the BBC to do this myself, so I think you are better equipped to do this.

Regards,
Ivo

@ivop
Copy link
Contributor Author

ivop commented Apr 5, 2024

I looked a bit more on porting it to the BBC and noticed the following:

  • MOS cannot read/write directly to/from sideways RAM. That'll mean that the overlay loader cannot load BDOS and BIOS directly to the memory banks and that the BIOS translation for READ and WRITE need to be changed to copy the data (take care of crossing bank borders) to/from a buffer outside of the memory bank.
  • Mode 3 takes a lot of memory. Only the Master 512 has enough free TPA to run the emulator.

I also briefly looked into the Apple ][ and I don't think a port would be viable. It banks the full lower 48K, banking out the 8080 registers and the emulator, so memory access would be really slow by having a piece of code somewhere in the 4kB banks above $c000. There are Z80 cards for the Apple. Better use one of them.

I also got a request to port it to the Neo6502. I asked how banked memory was done or if it's even available, but got no response. I suppose the RP2040 firmware could be updated to support 64kB of banked memory, preferably at $4000-$7fff so the N flag trick keeps working.

Lastly, I thought of a way to improve emulation speed by eliminating the instruction size table and moving loading the operands and increasing the program counter to each instruction that needs it. This would make the main emulation loop much faster by eliminating at least three instructions for the single byte opcodes, and double or triple that for the two and three byte opcodes. For two bye opcodes, I can probably even remove the intermediate storage in byte2 and use (PCL),y directly, saving two more instructions. Three byte opcodes will have to keep the ZP storage because of dereferencing it as an (adjusted) pointer. All this will increase the emulator's code size by several kilobytes, but I think it'll fit. Adding 800+ Z80 instructions wouldn't have fit anyway with the current fast unrolled and duplicated code for similar instructions.

@davidgiven
Copy link
Owner

That's really impressive. The performance is better than I was expecting --- have you tried something like WordStar on it? I suspect it won't update fast enough to be useful, but maybe...

Re the BBC: yes, the high resolution modes are basically a non-starter on a stock B with CP/M-65. You really need a Master or, preferably, a Tube system. The latter uses a completely different CPU to run user programs, with its own 64kB of memory, and system calls are sent via a fast link via RPCs. However, the Tube doesn't have banking so it wouldn't work for you.

Regarding the banking addresses... the BIT instruction loads bit 6 of the target into V. You know bit 7 will always be set, so a BIT/BNE will detect a change from $bfff to $c000. It'll corrupt A, but ought to be cheaper than an LDA/CMP depending on circumstances.

Re the RP2040: the Morpheus firmware package (the one with NeoBasic in it) only has space for the 64kB of main RAM and 20kB of graphics RAM. Last time I looked there was about 16kB free. To get more you'd have to change the firmware to remove stuff like the graphics subsystem, but that's a step down the slippery slope that ends up with emulating the 8080 on the RP2040... you could do banking via external RAM, like SPI-attached PSRAM, but again that would need a firmware change.

@ivop
Copy link
Contributor Author

ivop commented Apr 5, 2024

Thanks! I must say I was surprised by its performance, too. I currently have a 'faster' branch in the atari8080 repo which is even 10-15% faster.

Re the BBC, yeah I guessed the Tube wasn't able to use the sideways RAM banks. So only the Master 512 would be a viable option with screen memory in shadow RAM, and the 8080's 64kB in 4 banks of sideways RAM. The BIT trick is indeed useful. AFAIR BIT does not clobber A, so this should work:

(in INCPC macro):

inc PCH
inc PCHa ; adjusted high byte so (PCL) points inside extended memory bank
bit PCHa
bvc no_adjust
; recalculate PCHa from PCH and switch to next bank
no_adjust:

That's only one instruction longer than the Atari version. And even if A was clobbered, that doesn't matter for the code following.

Re Neo6502, I'll tell the person that asked that it's not possible 😄

I found a website with WordStar 1.0, 2.26, and 3.0 and onwards. It seems 3.0 introduced the Z80 dependency, so perhaps 2.26 will run. Hopefully it does vt52 and not ADM 3a. I'll look into it.

I have to rerun the testsuite after my ~13% speedup to see if nothing broke.

@ivop
Copy link
Contributor Author

ivop commented Apr 5, 2024

WordStar 2.26 runs! But... the install.com utility to change the terminal type does not support VT52. You can enter your own values, but you need to know the offsets into the binary. It literally asks for a hex offset and values. Those are in the WS manual, but I cannot find a WordStar 2 manual 😞

LOCATION TO BE CHANGED (0=END): 1234
    ADDRESS : 1234H   OLD VALUE: 41H   NEW VALUE: 

I did a binary diff on two different WS.COM files. One for Zenith H89/H19 and one for Televideo 912 and it appears we can detect where the terminal codes are stored. Then match with the terminal manuals and see what they do and replace with VT52 equivalents. Hopefully that'll be enough?

@ivop
Copy link
Contributor Author

ivop commented Apr 6, 2024

I just ignored the Z80 label on https://winworldpc.com/product/wordstar/330 and installed WordStar 3.3. WINSTALL.COM supports entering the escape sequences for what it needs (cursor positioning and clear-to-eol) and with tty80drv and vt52drv loaded it runs! No Z80 code at all.

But it's too slow to do any real work with it. Loading a file works, cursor movement works, but it's not responsive enough. With a CPU accelerator like Rapidus with a 65c816 at 20MHz it runs flawlessly though! I don't have the real hardware though. Perhaps I'll get one for my birthday 😉

@ivop
Copy link
Contributor Author

ivop commented Apr 10, 2024

I looked into a BBC port again, and I think I can make it work for every 128kB machine (B+128, Master128,Master512). At first I didn't get enough free TPA with the B+ and Master 128, but I found out I can force it to use shadow RAM by switching to mode 131 😄 After that, it should work. Tested bank switching with $f4 and $fe30. Found out $f4 is important as the DFS ROM is needed, which I suppose is exactly the reason why I can't read directly into sideways RAM. So switching banks will be one instruction longer, but in the end I think it will run faster than the Atari. The Atari is effectively running at around 1.35MHz when RAM refresh and screen DMA is subtracted. The BBC will run at a full 2MHz, so that's 45-50% faster. Curious to see how that works out.

@davidgiven
Copy link
Owner

You might be able to get away with only updating 0xf4 before making system calls. It's used to remember which language is currently bank in, so that after making a system call it can return to the right place. I have faint memories that interrupts store the current bank using a different mechanism.

@ivop
Copy link
Contributor Author

ivop commented Apr 12, 2024

The BBC Master 128/512 port now works.

Video: https://youtu.be/5uONG8YH2L0

As expected, it runs quite a bit faster than the 130XE version. Still too slow for WordStar 3.3. Its terminal handling is terrible and I suspect it wasn't particularly fast when run on original hardware to begin with.

There's no B+128K support, as that turned out to be not so easy to do in one binary. It would either need a re-assembled binary specifically for the B+128K (bank 0,1,12,13 instead of 4,5,6,7) or live patching itself, which are quite a few location to be patched. For now it's Master 128/512 only, in mode 131 with video memory in shadow RAM.

Because of lack of disk space, I have it create a second bbcmicro.ssd image with just the screen apps (for vt52drv). Similar to the Atari 130XE I put the 8080 loader, overlay and its 8080 binaries in user area 2. Even though this was never discussed, I sort of treat user area 0 for all cross-platform stuff, user area 1 for platform specific files (e.g. setfnt for the Atari) and user area 2 for 8080 CP/M. This minimizes the risk of accidentally running a .COM file for the wrong CPU and avoids filename clashes (e.g. DUMP.COM).

@ivop ivop changed the title Intel 8080 Emulator for the Atari 130XE Intel 8080 Emulator for the Atari 130XE and the BBC Master May 3, 2024
@ivop
Copy link
Contributor Author

ivop commented Aug 21, 2024

As several months have passed, what are your thoughts on this? Is it something you'd like to include in CP/M-65 or do you prefer it as a separate project? If it's the latter, I'll start releasing disk images at the atari8080 repo. People have been asking me for a bootable release 😄

@davidgiven
Copy link
Owner

So I'm in two minds about this. It makes sense to have it as part of the CP/M-65 distribution, but I don't really want to have checked in binaries. I do actually have a Z80/8080 assembler which could be easily integrated. OTOH I don't really want CP/M-65 to become a CP/M-80 distribution too...

Would it be feasible to have just the emulator stuff here, and then require a CP/M-80 disk obtained from elsewhere? Or does that just overcomplicate things?

@ivop
Copy link
Contributor Author

ivop commented Aug 23, 2024

Yeah, I was conflicted about it, too. Didn't know exactly what to put in third_party, and what not. 8080.s could be in included as we already have the Mad-Assembler as a requirement to build Altirra Basic. But it needs the CP/M-80 binaries to build (custom bios, bdos and ccp). As I didn't want to include the full build system of atari8080, I opted to include the binary blob and discuss later. Which is where we are now :)

So if we were to include 8080.s in the CP/M-65 build system, it either needs the 8080 bios.sys, bdos.sys and ccp.sys as binaries or build them from source, too. Once the emulator runs, it needs applications or it's useless. Halt.com would be mandatory so you don't have to reset the machine to return back to CP/M-65. As far as I know, multi-drive support in CP/M-65 is not yet working 100%, or has that been solved? If that was working, user area 2 on the boot disk (A:) could just include the overlay loader, the overlay and halt.com and the rest could be user supplied on drive B:.
Or I could keep maintaining my 8080ovl branch and periodically build disk images and release them through the atari8080 repo. I wouldn't mind doing that, and I can include a full CP/M-80 base system to make it more useful out of the box. You could then put a link in the BBC and Atari section of the CP/M-65 README.md to where people can download the 8080 emulator disk images.

Edit: thinking about it some more, the multi-drive solution might prove difficult with the file based approach the BBC port uses?

@davidgiven
Copy link
Owner

Could the 8080 code be loaded from the boot track of the CP/M-80 disk, mimicking the way that CP/M normally boots? That would neatly divide the 6502 code from the 8080 code (and the emulated CP/M-80 build could be easily added to my cpmish distribution). You'd put the CP/M-65 disk in A: and the CP/M-80 disk in B: and the overlay would do the mapping.

Multidrive support should work now, I think? Someone recently submitted a patch for it. I agree it's irritating on the BBC Micro. One of the things on my very long to-do list is to adapt the neo6502 code to do BDOS emulation on top of the MOS native hierarchical filesystem. Then the BIOS could be changed to do real disk access, so giving access to ADFS files as well as block access to the whole disk. One problem there is that ADFS only supports 10-character filenames, so there'd need to be a lot of subdirectory nesting...

@ivop
Copy link
Contributor Author

ivop commented Aug 24, 2024

That's an interesting idea. In theory, either the overlay loader or the emulator itself could read sectors or even files directly from drive B:. I guess the easiest would be for the overlay loader to load bios.sys, bdos.sys and ccp.sys from drive B: and mimic how it currently loads them directly to banked memory (with a detour via normal memory on the BBC because it can't load directly into sideways RAM). Prerequisite would be that drive B: has the same CP/M-65 disk layout as the host as it uses the host BIOS and BDOS to load the files. Theoretically it could load BIOS from the boot sector, but that would needlessly complicate things IMHO.

The 8080 disk could be built with your cpmish if you want to go fully open source, or with https://github.com/ivop/cpm22-from-source/ , to run the original DRI code (which BTW uses your ASM reimplementation with a wrapper to run directly on Linux, and it also compiles the original PL/M code with a ported ISIS compiler).

I'll look into multi drive support shortly. The Atari SD drive port could use an extra drive or two, and the Ohio Scientific Mini Floppy port (just 640 80kB per disk) that I have developed the last few days would definitely benefit from it, too. I'll send pull requests once I have that all working correctly.

As for the 8080 emulator, I'll revisit that when I'm done with my current projects. Too many things on my todo-list ;)

@iss000
Copy link
Contributor

iss000 commented Aug 26, 2024

Just a note: There is small bug in atari8080 which I pointed here: ivop/atari8080#3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants